package com.pcdandan.pcdandan.config;

import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.context.annotation.Scope;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.Environment;

import com.pcdandan.pcdandan.config.pipeline.DatabasePipeline;
import com.youyu.financial.gjj.crawler.annotation.ProcessScan;
import com.youyu.financial.gjj.crawler.pipeline.ConsolePipeline;
import com.youyu.financial.gjj.crawler.pipeline.Pipeline;
import com.youyu.financial.gjj.crawler.processor.ProcessorRegister;
import com.youyu.financial.gjj.crawler.processor.ServiceFactory;
import com.youyu.financial.gjj.crawler.processor.SpringProcessorRegister;
import com.youyu.financial.gjj.crawler.processor.SpringServiceFactory;
import com.youyu.financial.gjj.crawler.session.MemorySessionDao;
import com.youyu.financial.gjj.crawler.session.SessionDao;
import com.youyu.financial.gjj.crawler.session.SessionManager;
import com.youyu.financial.gjj.crawler.session.SimpleSessionManager;
import com.youyu.financial.gjj.crawler.visitor.SimpleVisitorGenerator;
import com.youyu.financial.gjj.crawler.visitor.VisitorGenerator;
import com.youyu.financial.gjj.crawler.visitor.http.ProxyFactory;
import com.youyu.financial.gjj.crawler.visitor.okhttp.OKHttpPool;
import com.youyu.financial.gjj.crawler.visitor.okhttp.OkHttpLogger;

import okhttp3.Interceptor;
import okhttp3.logging.HttpLoggingInterceptor;

/**
 * bean配置
 * User: zhouRongKang
 * Date: 2017/8/21
 * Time: 18:29
 */
@Configuration
@ProcessScan("com.pcdandan.pcdandan")
public class BeanConfiguration {

    private static Logger logger = LoggerFactory.getLogger(BeanConfiguration.class);

    @Autowired
    private Environment environment;

    /**
     * 会话持久实现类 redis实现
     *
     * @param redisTemplate
     * @return
     */
    @Bean
    public SessionDao redisSessionDao() {
        MemorySessionDao sessionDao = new MemorySessionDao();
        return sessionDao;
    }

    /**
     * session 管理器 默认使用内存版会话持久实现
     *
     * @param sessionDao
     * @return
     */
    @Bean
    public SessionManager sessionManager(SessionDao sessionDao) {
        Long timeout = 10 * 60 * 1000L;
        SimpleSessionManager.DEFAULT_SESSION_TIMEOUT = timeout;
        SimpleSessionManager simpleSessionManager = new SimpleSessionManager();
        simpleSessionManager.setSessionDao(sessionDao);
        simpleSessionManager.setTimout(timeout);
        simpleSessionManager.setEnableVlidationScheduler(false);
        return simpleSessionManager;
    }

    /**
     * 网络访问层连接池
     *
     * @return
     */
    @Bean
    public OKHttpPool okHttpPool() {
        OKHttpPool httpPool = new OKHttpPool(5000, 60);
        return httpPool;
    }

    /**
     * okhttp 日志拦截器
     *
     * @return
     */
    @Bean
    public Interceptor networkInterceptor() {
//        return new HttpLoggingInterceptor(new OkHttpLogger()).setLevel(HttpLoggingInterceptor.Level.HEADERS);
        return new HttpLoggingInterceptor(new OkHttpLogger()).setLevel(HttpLoggingInterceptor.Level.BODY);
    }


    /**
     * Visitor生成器 保证每个subject初始化都能获取唯一的Visitor
     *
     * @param okHttpPool
     * @param proxyFactory
     * @param networkInterceptor
     * @return
     */
    @Bean
    public VisitorGenerator visitorGenerator(OKHttpPool okHttpPool, ProxyFactory proxyFactory, Interceptor networkInterceptor) {
        SimpleVisitorGenerator visitorGenerator = new SimpleVisitorGenerator();
        visitorGenerator.setOkHttpPool(okHttpPool);
        visitorGenerator.setProxyFactory(proxyFactory);
        visitorGenerator.setNetworkInterceptors(new ArrayList() {{
//            add(new CookieInterceptor());
            //add(new CookieInterceptor());
//            add(new PinpointInterceptor());
//            add(new LoggingInterceptor());
            add(networkInterceptor);
        }});
        return visitorGenerator;
    }

    /**
     * SpringServiceFactory 用作在spring环境下，会将所有spring bean 当做服务
     * SimpleServiceFactory 用作在非spring环境下 ，服务需要手动初始
     *
     * @return
     */
    @Bean
    public ServiceFactory serviceFactory() {
        ServiceFactory serviceFactory = new SpringServiceFactory();
//        ServiceFactory serviceFactory = new SimpleServiceFactory();
        return serviceFactory;
    }

    /**
     * 业务逻辑处理器注册中心
     * SpringProcessorRegister：spring环境下的自动扫描注册中心
     * SimpleProcessorRegister：基于自定义注解自动扫描处理器的注册中心
     * GroovyProcessorRegister：Groovy脚本动态加载注册中心
     *
     * @return
     */
    @Bean
    public ProcessorRegister processorRegisterDev(ServiceFactory serviceFactory) {
//        ProcessorRegister processorRegister = new SimpleProcessorRegister("com.youyu");
        ProcessorRegister processorRegister = new SpringProcessorRegister();
//        初始化 - groovy脚本目录
//        String classpath = BillCrawler.class.getResource("/").getFile();
//        String path = classpath.substring(0, classpath.indexOf("target")) + "/src/main/java/com/youyu/financial/bill/processor";
//        File directory = new File(path);
//        //过滤掉的文件
//        //NotFileFilter notFileFilter = new NotFileFilter(new NameFileFilter(new String[]{"SiBaseProcessor.java"}));
//        SpringGroovyProcessorRegister processorRegister = new SpringGroovyProcessorRegister(directory, null, serviceFactory, 0, 5000L);
        return processorRegister;
    }


    @Bean
    @Order(2)
    public Pipeline databasePipeline() {
        return new DatabasePipeline();
    }

    @Bean
    @Order(1)
    public Pipeline consolePipeline() {
        return new ConsolePipeline();
    }

    /**
     * 爬虫实例
     *
     * @param processorRegister
     * @param sessionManager
     * @param visitorGenerator
     * @return
     */
    @Bean
    @Scope("prototype")
    public PcdandanCrawler crawler(ProcessorRegister processorRegister, SessionManager sessionManager, VisitorGenerator visitorGenerator, List<Pipeline> pipelines) {
        PcdandanCrawler crawler = new PcdandanCrawler();
        crawler.setProcessorRegister(processorRegister);
        crawler.setSessionManager(sessionManager);
        crawler.setVisitorGenerator(visitorGenerator);
        crawler.setPipelines(pipelines);
        return crawler;
    }


}

    